﻿namespace MicroCloud.EventBuses
{
    /// <summary>
    /// 事件处理器基类
    /// <para>EventBus中，Handler的调用是同步执行的，如果需要触发就不管的异步执行，可以在实现EventHandler的Handle逻辑时使用Task.Run。</para>
    /// </summary>
    public abstract class EventHandlerBase<TEventData> : IEventHandler<TEventData> where TEventData : IEventData
    {  
        /// <summary>
        /// 是否可处理指定事件
        /// </summary>
        /// <param name="eventData">事件源数据</param>
        /// <param name="provider">服务提供者</param>
        /// <returns>是否可处理</returns>
        public virtual bool CanHandle(IEventData eventData, IServiceProvider provider)
        {
            return eventData.GetType() == typeof(TEventData);
        }

        /// <summary>
        /// 事件处理
        /// </summary>
        /// <param name="eventData">事件源数据</param>
        /// <param name="provider">服务提供者</param>
        public void Handle(IEventData eventData, IServiceProvider provider)
        {
            if (!CanHandle(eventData, provider))
            {
                return;
            }
            Handle((TEventData)eventData, provider);
        }

        /// <summary>
        /// 异步事件处理
        /// </summary>
        /// <param name="eventData">事件源数据</param>
        /// <param name="provider">服务提供者</param>
        /// <param name="cancelToken">异步取消标识</param>
        /// <returns></returns>
        public async Task HandleAsync(IEventData eventData, IServiceProvider provider, CancellationToken cancelToken = default)
        {
            if (!CanHandle(eventData, provider))
            {
                await Task.CompletedTask;
            }
            await HandleAsync((TEventData)eventData, provider, cancelToken);
        }

        /// <summary>
        /// 事件处理
        /// <para>EventBus中，Handler的调用是同步执行的，如果需要触发就不管的异步执行，可以在实现EventHandler的Handle逻辑时使用Task.Run。</para>
        /// </summary>
        /// <param name="eventData">事件源数据</param>
        /// <param name="provider">服务提供者</param>
        public abstract void Handle(TEventData eventData, IServiceProvider provider);

        /// <summary>
        /// 异步事件处理
        /// </summary>
        /// <param name="eventData">事件源数据</param>
        /// <param name="provider">服务提供者</param>
        /// <param name="cancelToken">异步取消标识</param>
        /// <returns>是否成功</returns>
        public virtual async Task HandleAsync(TEventData eventData, IServiceProvider provider, CancellationToken cancelToken = default)
        {
            await Task.Run(() => Handle(eventData, provider), cancelToken);
        }

    }
}